package cn.abcsys.cloud.devops.runtime.core.impl;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSONObject;
import com.github.dockerjava.api.DockerClient;

import cn.abcsys.cloud.devops.runtime.bean.Result;
import cn.abcsys.cloud.devops.runtime.common.Constant;
import cn.abcsys.cloud.devops.runtime.common.SystemConfig;
import cn.abcsys.cloud.devops.runtime.core.ImageCore;
import cn.abcsys.cloud.devops.runtime.model.ImageObject;
import cn.abcsys.cloud.devops.runtime.utils.CommandExcutor;
import cn.abcsys.cloud.devops.runtime.utils.IOUtils;
import cn.abcsys.cloud.devops.runtime.utils.SSH;
@Component
public class ImageCoreImpl implements ImageCore {
	protected DockerClient dockerClient;
	@Autowired
	private SystemConfig systemConfig;
    @Override
    public Result scanImage(JSONObject paramIn) {
        SSH ssh = new SSH(paramIn.getString("pipelineHostIp"), 
				paramIn.getString("pipelineHostUser"), paramIn.getString("pipelineHostPwd"));
        StringBuffer sb = new StringBuffer();
        boolean flag = false;
        String imageUuid = paramIn.getString("imageUuid");
        try {
            if (ssh.connect()) {
                String scanCommand = "sh /usr/bin/scanner " + imageUuid + " > /tmp/scanner_result_" + imageUuid + ".txt 2>&1";
                String result = ssh.executeWithResult(scanCommand);
                ssh.close();
            }
            if (ssh.connect()) {
                //判断本机路径是否存在，不存在创建
                String imageClairLogsPath = paramIn.getString("imageClairLogsPath");
                IOUtils.createFile(imageClairLogsPath, "/scanner_result_" + imageUuid + ".txt");
                flag = ssh.fetchFile("/tmp/scanner_result_" + imageUuid + ".txt", imageClairLogsPath);
                if (flag) {
                    File file = new File(imageClairLogsPath + "/scanner_result_" + imageUuid + ".txt");
                    BufferedReader reader = null;
                    try {
                        reader = new BufferedReader(new FileReader(file));
                        String tempString = null;
                        int line = 1;
                        // 一次读入一行，直到读入null为文件结束
                        while ((tempString = reader.readLine()) != null) {
                            // 显示行号
                            sb.append(tempString + "\n");
                            line++;
                        }
                        reader.close();
                    } catch (IOException e) {
                        return new Result(false, "read scan file error:"+e.getMessage());
                    } finally {
                        if (reader != null) {
                            try {
                                reader.close();
                            } catch (IOException e) {
                            	return new Result(false, "read scan file error:"+e.getMessage());
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            return new Result(false, "Scan Images Error!"+e.getLocalizedMessage());
        } finally {
            ssh.close();
        }

        if (flag) {
            return new Result(true, sb.toString().replace("\n", "<br>"),"success");
        } else {
            return new Result(false, "Scan Images Error!Error during SCP transfer!No such file or directory!");
        }
    }

    @Override
    public Result showImageScanResult(JSONObject paramIn) {
    	String imageUuid = paramIn.getString("imageUuid");
    	String imageClairLogsPath = paramIn.getString("imageClairLogsPath");
        StringBuffer sb = new StringBuffer();
        File file = new File(imageClairLogsPath + "scanner_result_" + imageUuid + ".txt");
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(file));
            String tempString = null;
            // 一次读入一行，直到读入null为文件结束
            while ((tempString = reader.readLine()) != null) {
                // 显示行号
                sb.append(tempString + "\n");
            }
            reader.close();
        } catch (IOException e) {
        	return new Result(false, "read scan file error:"+e.getMessage());
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                	return new Result(false, "read scan file error:"+e.getMessage());
                }
            }
        }
        return new Result(true, sb.toString().replace("\n", "<br>"));
    }
    
    @Override
    public Result pushImage(JSONObject paramIn) {
    	String imageName = paramIn.getString("imageName"); 
    	String imageTag = paramIn.getString("imageTag"); 
    	String imageFullName = paramIn.getString("imageFullName"); 
    	String hostname = paramIn.getString("hostname");
    	String username = paramIn.getString("username");
    	String password = paramIn.getString("password");
    	SSH ssh = new SSH(hostname, username, password);
        try {
            if (ssh.connect()) {
                StringBuilder commandStr = new StringBuilder();
                commandStr.append("docker tag "+ imageName+":"+imageTag+" "+imageFullName
                		+";docker push " + imageFullName);
                try {
                    String result = ssh.executeWithResult(commandStr.toString());
                    if (result.contains("Error")||result.contains("error") || 
                    		result.contains("failed") || result.contains("EOF")) {
                        return new Result(false, "镜像发布脚本执行失败！");
                    } else if (result.contains("Cannot connect to the Docker daemon.")) {
                        return new Result(false, "【制作镜像失败】：仓库主机上的Docker服务异常！");
                    } else if (result.contains("refused")) {
                        return new Result(false, "仓库服务调用异常");
                    } else {
                        return new Result(true,result, "镜像发布成功！");
                    }
                } catch (Exception e) {
                    return new Result(false, "发布镜像失败：发布镜像脚本执行异常！");
                } 
            } else {
                return new Result(false, "镜像发布失败：连接仓库主机异常！");
            }
        } catch (Exception e) {
            return new Result(false, "镜像发布失败：SSH无法连接仓库主机！请检查主机运行状态、网络连接状态或核对输入正确的用户名和密码。");
        }finally {
            ssh.close();
        }
    }
    @Override
    public Result uploadImage(JSONObject paramIn){
    	String targetFolder = paramIn.getString("targetFolder");
    	String fileName = paramIn.getString("fileName");
    	String hostname = paramIn.getString("hostname");
    	String username = paramIn.getString("username");
    	String password = paramIn.getString("password");
    	SSH ssh = new SSH(hostname, username, password);
    	if (!fileName.endsWith(".tar")) {
            return new Result(false, "制作基础镜像异常：不支持此类文件(" + fileName + ")类型，只支持*.tar文件！");
        }
    	
    	
    	
    	//step1:检查tar文件是否存在,将repostories文件解析到本地
    	String step1_command = "cd "+targetFolder+" && tar xvf "+fileName+" repositories &>/dev/null && ls repositories";
    	try{
    		if(ssh.connect()){
    			String fileExist = ssh.executeWithResult(step1_command);
    			System.out.println("ls repositories :"+fileExist);
    			if(!Constant.repositories.equals(fileExist.replaceAll("\n", ""))){
    				return new Result(false, "失败原因：1.没找到镜像包文件；2.镜像文件repositories解析异常，可能不是正常的镜像包");
    			}
    		}else{
    			return new Result(false, "SSH无法连接仓库主机！请检查主机运行状态、网络连接状态或核对输入正确的用户名和密码。");
    		}
    	}catch (Exception e) {
            return new Result(false, "镜像制作失败：SSH无法连接仓库主机！请检查主机运行状态、网络连接状态或核对输入正确的用户名和密码。");
        }finally {
    		ssh.close();
		}
    	//step2:读取repostories文件
    	String step2_command = "cat "+targetFolder+"/repositories";
    	List<ImageObject> imageObjects = new ArrayList<>();
    	try{
    		if(ssh.connect()){
    			String file_Stream = ssh.executeWithResult(step2_command);
    			System.out.println("repositories:"+file_Stream);
    			if(StringUtils.isEmpty(file_Stream)){
    				return new Result(false, "镜像文件repositories解析异常，可能不是正常的镜像包。");
    			}
    			JSONObject repositories_json = JSONObject.parseObject(file_Stream);
    	    	Set<String> repositories_set = repositories_json.keySet();
    	    	Iterator<String> repositories_iterator = repositories_set.iterator();
    	    	while(repositories_iterator.hasNext()){
    	    		String imageName = repositories_iterator.next();
    	    		System.out.println("imageName:"+imageName);
    	    		JSONObject tag_json = JSONObject.parseObject(repositories_json.get(imageName).toString());
    	    		Set<String> tag_set = tag_json.keySet();
    	        	Iterator<String> tag_iterator = tag_set.iterator();
    	        	while(tag_iterator.hasNext()){
    	        		String imageTag = tag_iterator.next();
    	        		System.out.println("imageTag:"+imageTag);
    	        		System.out.println("imageUuid:"+tag_json.get(imageTag));
    	        		ImageObject imageObject = new ImageObject(imageName, imageTag, tag_json.get(imageTag).toString());
    	        		imageObjects.add(imageObject);
    	        	}
    	    	}
    		}else{
    			return new Result(false, "SSH无法连接仓库主机！请检查主机运行状态、网络连接状态或核对输入正确的用户名和密码。");
    		}
    	}catch (Exception e) {
            return new Result(false, "镜像制作失败：SSH无法连接仓库主机！请检查主机运行状态、网络连接状态或核对输入正确的用户名和密码。");
        }finally {
    		ssh.close();
		}
    	//setp3:上传镜像
//    	try{
//    		if(ssh.connect()){
//    			String fileExist = ssh.executeWithResult(step1_command);
//    			if(!Constant.repositories.equals(fileExist)){
//    				return new Result(false, "镜像文件解析异常，repositories文件不存在，可能不是正常的镜像包。");
//    			}
//    		}else{
//    			return new Result(false, "SSH无法连接仓库主机！请检查主机运行状态、网络连接状态或核对输入正确的用户名和密码。");
//    		}
//    	}catch (Exception e) {
//            return new Result(false, "镜像制作失败：SSH无法连接仓库主机！请检查主机运行状态、网络连接状态或核对输入正确的用户名和密码。");
//        }finally {
//    		ssh.close();
//		}
    	StringBuilder commandStr = new StringBuilder();
        if (fileName.endsWith(".tar")) {
            commandStr.append("docker load --input " + targetFolder + "/" + fileName + ";");
            /* 删除整个保存上传文件文件夹 */
            commandStr.append("rm -rf " + targetFolder + "/;");
        } else {
            return new Result(false, "制作基础镜像异常：不支持此类文件(" + fileName + ")类型！");
        }
        try {
            if (ssh.connect()) {
                String command = commandStr.toString();
                String result = ssh.executeWithResult(command.toString());
                Result re  = processMakeImageResult(result);
                if(!re.isSuccess()){
                	return re;
                }
                return new Result(true, imageObjects,"make image success");
            } else {
                return new Result(false, "SSH无法连接仓库主机！请检查主机运行状态、网络连接状态或核对输入正确的用户名和密码。");
            }
        } catch (Exception e) {
            return new Result(false, "镜像制作失败：SSH无法连接仓库主机！请检查主机运行状态、网络连接状态或核对输入正确的用户名和密码。");
        } finally {
            ssh.close();
        }
    }
    /**
     * @param basic
     * @param response
     * @return
     */
    private Result processMakeImageResult(String response) {
        if (response.contains("cannot find or open")) {
            return new Result(false, "【应用包解压失败】：应用文件压缩包不存在！可能被其他用户后台删除");
        } else if (response.contains("Cannot connect to the Docker daemon.")) {
            return new Result(false, "【制作镜像失败】：仓库主机上的Docker服务异常！");
            /** @bug219_begin:[镜像管理]制作镜像,当找不到文件夹或文件而制作失败,请将该错误原因返回给终端 **/
        } else if (response.toLowerCase().contains("no such file or directory")) {
            return new Result(false, "【制作镜像失败】：仓库主机上无法找到与制作镜像相关的文件或文件夹！");
        } else if (response.toLowerCase().contains("no such id")) {
            return new Result(false, "【制作镜像失败】：tag失败");
        } else if (response.toLowerCase().contains("Error")) {
            return new Result(false, "【制作镜像失败】：未知错误");
        }else{
        	return new Result(true, "");
        }
    }

}
